package com.wl.shop.utils;

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Lists;
import com.wl.shop.dao.AreaDao;
import com.wl.shop.dao.CategoryDao;
import com.wl.shop.dao.MenuDao;
import com.wl.shop.dao.RoleDao;
import com.wl.shop.dao.UserDao;
import com.wl.shop.entity.Area;
import com.wl.shop.entity.Category;
import com.wl.shop.entity.Menu;
import com.wl.shop.entity.Role;
import com.wl.shop.entity.User;
import com.wl.shop.model.ZtreeVO;
import com.wl.shop.security.SystemAuthorizingRealm.ShiroUser;

/**
 * 用户工具类
 * @author wl
 *
 */
public class UserUtils {
	private static UserDao userDao = SpringContextHolder.getBean(UserDao.class);
	private static RoleDao roleDao = SpringContextHolder.getBean(RoleDao.class);
	private static MenuDao menuDao = SpringContextHolder.getBean(MenuDao.class);
	private static AreaDao areaDao = SpringContextHolder.getBean(AreaDao.class);
	private static CategoryDao categoryDao = SpringContextHolder.getBean(CategoryDao.class);
	
	public static final String USER_CACHE = "userCache";
	public static final String USER_CACHE_ID_ = "id_";
	public static final String USER_CACHE_LOGIN_NAME_ = "ln";
	
	public static final String CACHE_ROLE_LIST = "roleList";
	public static final String CACHE_MENU_LIST = "menuList";
	public static final String CACHE_AREA_LIST = "areaList";
	public static final String CACHE_TREE_MENU_STRING = "treeMenuString";
	public static final String CACHE_TREE_CATEGORY_STRING = "treeCategoryString";
	/**
	 * 根据ID获取用户
	 * @param id
	 * @return 取不到返回null
	 */
	public static User get(String id){
		User user = (User)CacheUtils.get(USER_CACHE, USER_CACHE_ID_ + id);
		if (user ==  null){
			user = userDao.selectById(id);
			if (user == null){
				return null;
			}
			user.setRoleList(roleDao.selectRoleByUserId(id));
			CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
			CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
		}
		return user;
	}
	
	/**
	 * 清除当前用户缓存
	 */
	public static void clearCache(){
		removeCache(CACHE_ROLE_LIST);
		removeCache(CACHE_MENU_LIST);
		removeCache(CACHE_AREA_LIST);
		UserUtils.clearCache(getUser());
	}
	
	/**
	 * 清除指定用户缓存
	 * @param user
	 */
	public static void clearCache(User user){
		CacheUtils.remove(USER_CACHE, USER_CACHE_ID_ + user.getId());
		CacheUtils.remove(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginName());
	}
	
	/**
	 * 获取当前用户
	 * @return 取不到返回 new User()
	 */
	public static User getUser(){
		ShiroUser principal = getPrincipal();
		if (principal!=null){
			User user = get(principal.getId());
			if (user != null){
				return user;
			}
			return new User();
		}
		// 如果没有登录，则返回实例化空的User对象。
		return new User();
	}
	
	/**
	 * 获取当前登录者对象
	 */
	public static ShiroUser getPrincipal(){
		try{
			Subject subject = SecurityUtils.getSubject();
			ShiroUser principal = (ShiroUser)subject.getPrincipal();
			if (principal != null){
				return principal;
			}
//			subject.logout();
		}catch (UnavailableSecurityManagerException e) {
			
		}catch (InvalidSessionException e){
			
		}
		return null;
	}
	
	/**
	 * 获取授权主要对象
	 */
	public static Subject getSubject(){
		return SecurityUtils.getSubject();
	}
	
	public static Session getSession(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Session session = subject.getSession(false);
			if (session == null){
				session = subject.getSession();
			}
			if (session != null){
				return session;
			}
//			subject.logout();
		}catch (InvalidSessionException e){
			
		}
		return null;
	}
	
	/**
	 * 根据登录名获取用户
	 * @param loginName
	 * @return 取不到返回null
	 */
	public static User getByLoginName(String loginName){
		User user = (User)getCache(USER_CACHE);
		if(user == null){
			user = userDao.selectOne(new User(null,loginName));
			if (user == null){
				return null;
			}
			putCache(USER_CACHE, user);
		}
		return user;
	}
	
	/**
	 * 获取当前用户授权菜单
	 * @return
	 */
	public static List<Menu> getMenuList(){
		@SuppressWarnings("unchecked")
		List<Menu> menuList = (List<Menu>)getCache(CACHE_MENU_LIST);
		if (menuList == null){
			User user = getUser();
			if (user.isAdmin()){
				try {
					menuList = menuDao.selectList(new EntityWrapper<Menu>());
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
				
			}else{
				menuList = menuDao.selectMenuByUserId(user.getId());
			}
			putCache(CACHE_MENU_LIST, menuList);
		}
		return menuList;
	}
	
	/**
	 * 获取当前用户角色列表
	 * @return
	 */
	public static List<Role> getRoleList(){
		@SuppressWarnings("unchecked")
		List<Role> roleList = (List<Role>)getCache(CACHE_ROLE_LIST);
		if (roleList == null){
			User user = getUser();
			if (user.isAdmin()){
				EntityWrapper<Role> wrapper = new EntityWrapper<Role>();
				wrapper.eq("is_del", false);
				roleList = roleDao.selectList(wrapper);
			}else{
				roleList = roleDao.selectRoleByUserId(user.getId());
			}
			putCache(CACHE_ROLE_LIST, roleList);
		}
		return roleList;
	}
	
	/**
	 * 获取菜单树
	 * @return
	 */
	public static String getMenuTreeString(){
		String treeString = (String)getCache(CACHE_TREE_MENU_STRING);
		if(StringUtils.isBlank(treeString)){
			List<ZtreeVO> tree = getMenuTree();
			treeString = JSON.toJSONString(tree);
			putCache(CACHE_TREE_MENU_STRING, treeString);
		}
		return treeString;
	}
	
	/**
	 * 获取栏目树
	 * @return
	 */
	public static String getCategoryTreeString(){
		String treeString = (String)getCache(CACHE_TREE_CATEGORY_STRING);
		if(StringUtils.isBlank(treeString)){
			List<ZtreeVO> trees = getCategoryTree();
			treeString = JSON.toJSONString(trees);
			putCache(CACHE_TREE_CATEGORY_STRING, treeString);
		}
		return treeString;
	}
	
	
	
	/**
	 * 递归拉取菜单树的数据
	 * @param id
	 * @return
	 */
	public static ZtreeVO getZTree(String id){
		EntityWrapper<Menu> wrapper = new EntityWrapper<Menu>();
		wrapper.eq("is_del", false).eq("parent_id", id).orderBy("sort");
		List<Menu> rootMenu = menuDao.selectList(wrapper);
		ZtreeVO ztree = new ZtreeVO();
		ztree.setCategoryId(id);
		if("1".equals(id)){
			ztree.setName("根目录");
		}else{
			Menu m = menuDao.selectById(id);
			if(m == null) {
				return null;
			}else{
				ztree.setName(m.getName());
			}
		}
		List<ZtreeVO> childList = Lists.newArrayList();
		for (Menu menu : rootMenu) {
			ZtreeVO c = getZTree(menu.getId());
			childList.add(c);
		}
		if(rootMenu != null && rootMenu.size()>0){
			ztree.setOpen(true);
			ztree.setChildren(childList);
		}
		return ztree;
	}
	
	/**
	 * 利用Ztree的simpleData数据格式
	 * @return
	 */
	public static List<ZtreeVO> getMenuTree(){
		EntityWrapper<Menu> wrapper = new EntityWrapper<Menu>();
		wrapper.eq("is_del", false).orderBy("sort");
		List<Menu> menuList = menuDao.selectList(wrapper);
		List<ZtreeVO> trees = Lists.newArrayList();
		for (Menu menu : menuList) {
			ZtreeVO ztree = new ZtreeVO();
			ztree.setId(menu.getId());
			ztree.setPid(menu.getParentId());
			ztree.setName(menu.getName());
			ztree.setOpen(true);
			trees.add(ztree);
		}
		return trees;
	}
	
	/**
	 * 递归拉取栏目树的数据
	 * @param id
	 * @return
	 */
	public static List<ZtreeVO> getCategoryTree(){
		EntityWrapper<Category> wrapper = new EntityWrapper<Category>();
		wrapper.eq("is_del", false).orderBy("sort");
		List<Category> rootCategory = categoryDao.selectList(wrapper);
		List<ZtreeVO> trees = Lists.newArrayList();
		for (Category category : rootCategory) {
			ZtreeVO ztree = new ZtreeVO();
			ztree.setId(category.getId());
			ztree.setPid(category.getParentId());
			ztree.setName(category.getName());
			trees.add(ztree);
		}
		
//		ztree.setCategoryId(id);
//		if("1".equals(id)){
//			Site site = siteDao.selectById("1");
//			ztree.setName(site.getSiteName());
//		}else{
//			Category category = categoryDao.selectById(id);
//			if(category == null) {
//				return null;
//			}else{
//				ztree.setName(category.getName());
//			}
//		}
//		List<ZtreeVO> childList = Lists.newArrayList();
//		for (Category c : rootCategory) {
//			ZtreeVO z = getCategoryTree(c.getId());
//			childList.add(z);
//		}
//		if(rootCategory != null && rootCategory.size()>0){
//			ztree.setOpen(true);
//			ztree.setChildren(childList);
//		}
		return trees;
	}
	
	/**
	 * 获取当前用户授权的区域
	 * @return
	 */
	public static List<Area> getAreaList(){
		@SuppressWarnings("unchecked")
		List<Area> areaList = (List<Area>)getCache(CACHE_AREA_LIST);
		if (areaList == null){
			EntityWrapper<Area> wrapper = new EntityWrapper<Area>();
			wrapper.eq("is_del", false);
			areaList = areaDao.selectList(wrapper);
			putCache(CACHE_AREA_LIST, areaList);
		}
		return areaList;
	}
	
	
	
	// ============== User Cache ==============
	
		public static Object getCache(String key) {
			return getCache(key, null);
		}
		
		public static Object getCache(String key, Object defaultValue) {
//			Object obj = getCacheMap().get(key);
			Object obj = getSession().getAttribute(key);
			return obj==null?defaultValue:obj;
		}

		public static void putCache(String key, Object value) {
//			getCacheMap().put(key, value);
			getSession().setAttribute(key, value);
		}

		public static void removeCache(String key) {
//			getCacheMap().remove(key);
			getSession().removeAttribute(key);
		}
}
